3-1 Mj埻z

本節介紹 Perl 的控制結構,大概可分為下列數大類: 在條件敘述中,最常見的就是 if 敘述,其一般格式如下: If (condition1) { … } elsif (condition2) { … } else { ... } 其中「elsif」部分可以重複很多次。例如(tif.pl):

原始檔(tif.pl):(灰色區域按兩下即可拷貝)
@alldays = ("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun");
$num = rand(scalar @alldays);
$thisday = @alldays[$num];
if ($thisday eq "Sat") {
	$type = "holiday";
} elsif ($thisday eq "Sun") {
	$type = "holiday";
} else {
	$type = "workday";
}
print("$thisday is a $type.");

在上面的範例中,「scalar @alldays」會傳回 7,代表 @alldays 的元素個數,「rand(scalar @alldays)」則會傳回一個介於 [0, 7) 區間的亂數,因此 $thisday 的值就可能是 $alldays 中的任一個元素。若 $thisday 是 "Sat" 或 "Sun",則 $type 是 "holiday",否則,$type$ 是 "workday"。

對於簡單的 if 敘述,我們也可以把 if 的條件部分放到後面,例如,下列兩列程式碼是完全等效的:

if ($x > 0) {print("$x is positive");} print("$x is positive") if ($x > 0); 上述的第二列程式碼是比較符合美式口語的說法,但在一般電腦程式語言卻很少見到。

另一個條件敘述是 unless,是在判斷條件不為真的情況下,才執行其後的敘述。例如:

unless ($x <= 0) { print("$x is positive"); } 和 if 敘述相同,我們也可以把 unless 的條件判斷部分搬到後面。

綜合上面的說明,我們可發覺,下面六列程式碼的功能是完全一樣的:

1. if ($x > 0) {print "positive\n";}; 2. print "positive\n" if ($x > 0); 3. unless ($x <= 0) {print "positive\n";}; 4. print "positive\n" unless ($x <= 0); 5. $x > 0 && print "positive\n"; 6. $x <= 0 || print "positive\n"; 在上例第五列中,「&&」代表邏輯的「AND」運算,因此只要第一個運算子是 0(即不滿足 $x > 0),則不再執行第二個運算子(即不印出 "positive")。同理,在第六列中,「||」代表邏輯的「OR」運算,因此只要第一個運算子是 0(即滿足 $x <= 0),則不再執行列印動作。

在條件敘述中,Perl 如何判斷一個運算式是 True (真)或 False (偽)呢?其根據的原則如下:

  1. 將運算結果視為一個字串。
  2. 如果運算結果是 "0" 或 ""(空字串)或 undef (未定義),則代表結果為 False,否則即為 True。
以下這些範例讓讀者自行參考及推想:

條件敘述判定結果
0False
1-1False
1True
""False
"1"True
"00"True
"0.000"True
undefFalse

接下來我們要說明的是迴圈敘述(Loop Statement)。首先說明的是 while/until 迴圈敘述,其基本格式如下:

while (條件式) { 迴圈內部敘述 } until (條件式) { 迴圈內部敘述 } do { 迴圈內部敘述 } while (條件式); do { 迴圈內部敘述 } until (條件式); 前兩種格式是先判斷條件式,再決定是否執行迴圈內部敘述;後兩種格式是先執行迴圈內部敘述後,再判斷條件式,決定是否繼續執行迴圈。

另一個常用到的迴圈敘述是 for 迴圈,其格式和 C 語言的 for 迴圈很類似。在下例中,我們利用 for 迴圈將陣列的元素逐一印出:

@days = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"); for ($i=0; $i<7; $i++) { print("$days[$i]"; } Perl 也提供了另一種專門適用於陣列變數的 foreach 迴圈,我們可用 foreach 迴圈將上述程式碼改寫如下: @days = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"); foreach $element (@days) { print("$element"); } 其中 $element 的值會依序被設定為陣列 @days 的每一個元素,然後再執行期後的列印動作。事實上,上例可以再被簡化如下: @days = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"); foreach (@days) { print; } 換句話說,$element已被省略,Perl 會自行取用一個虛擬變數 $_ 來取代 $element 的角色,此虛擬變數也是 foreach 和 print 的預設引數(Default Argument)。

若要從迴圈中即刻跳出,可用 last,其效果和 C 語言的 break 是相同的。例如,在處理陣列 $array 的元素時,若任一個元素值為負數時,則完全跳出迴圈,並由迴圈之後的敘述開始執行,其程式碼為:

for ($i = 0; $i < 10; $i++) { last if $array[$i] < 0; … } 在另一種情況下,我們可能需要結束此次迴圈的執行,並立刻跳至下一個迴圈的開始位置來執行,此功能可由 next 來達成,其效果和 C 語言的 continue 是相同的。例如,在處理陣列 $array 的元素時,若任一個元素值為負數時,則立刻跳出此次迴圈,並由下次迴圈開始執行,其程式碼為: foreach $element (@array) { next if $element < 0; ... } 由此我們可看出,Perl 的 last 相當於 C 的 break,而 Perl 的 next 相當於 C 的 continue。
Perl